package servlets;
import entidades.*;
import util.*;

import java.util.Map;
import java.util.Date;
import java.util.List;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 * @author JFM
 */
public class Excel extends HttpServlet
	{
	@Override
	public void init(ServletConfig conf) throws ServletException
		{
		super.init(conf);
		}



	@Override
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
		{
		try{
			// Obtengo el tipo.
			String tipo = (request.getParameter("tipo") != null)? request.getParameter("tipo") : "";

			// Genero la planilla.
			response.setContentType("application/octet-stream");
			response.setHeader("Content-Disposition","attachment;filename=" + tipo + ".xls");

			ServletOutputStream outputStream = response.getOutputStream();

			if(tipo.compareTo("disponibleParaPrometer") == 0)
				{ disponibleParaPrometer(request, outputStream); }

			if(tipo.compareTo("listaOrdenesVenta") == 0)
				{ listaOrdenesVenta(request, outputStream); }

			if(tipo.compareTo("listaOrdenesTrabajo") == 0)
				{ listaOrdenesTrabajo(request, outputStream); }

			if(tipo.compareTo("programacion") == 0)
				{ programacion(request, outputStream); }
                        if(tipo.compareTo("programacionNewlong") == 0)
				{ programacionNewlong(request, outputStream); }

			if(tipo.compareTo("scada") == 0)
				{ listaScada(request, outputStream); }

			outputStream.flush();
			outputStream.close();
			}catch(Exception e) {
                            System.out.print(1);
                        }

		response.sendRedirect(request.getParameter("redirect"));
		}



	public void disponibleParaPrometer(HttpServletRequest request, OutputStream outputStream) throws Exception
		{
                // Obtengo el pais
                Integer pais = Integer.parseInt(request.getParameter("excel_pais"));    
                    
		// Creo el archivo Excel y defino la primer hoja.
		Workbook workbook = new HSSFWorkbook();
		Sheet hoja = workbook.createSheet("Disponible");

		// Defino las fuentes.
		CellStyle titulo = titulo(workbook);
		CellStyle contenido = contenido(workbook);

                //Obtengo los ciclos disponibles
                Map<Integer, List<Map>> disponible = CicloNewlong.disponibleParaPrometer(pais);
                
		// Escribo la cabecera.
		Row fila0 = hoja.createRow(0);
		Row fila1 = hoja.createRow(1);
		String subtitulos[] = {"Entrega", "Cant"};
		for(int i=0; i<disponible.size() && i<15; i++){
			// Combino las celdas en las que va el numero.
			hoja.addMergedRegion(new CellRangeAddress(0, 0, 1 + i*subtitulos.length, 1 + i*subtitulos.length + 1));

			// Escribo el numero.
			Cell numero = fila0.createCell(1 + i*subtitulos.length);
			numero.setCellStyle(titulo);
			numero.setCellValue(i + 1);

			// Escribo los subtitulos.
			for(int j=0; j<subtitulos.length; j++)
				{
				Cell sub = fila1.createCell(1 + i*subtitulos.length + j);
				sub.setCellStyle(titulo);
				sub.setCellValue(subtitulos[j]);
				}
		}
                
                // Escribo las fechas.
        	List<Formato> formatos = Formato.listar();
                for(int i=0, j=i; i<formatos.size(); i++){
                    // Obtengo la lista de los ciclos disponibles y estimo las fechas y las cantidades.
                    List<Map> ciclos = disponible.get(formatos.get(i).getId());
                    
                    if (ciclos.size()>0){
                        
                        Row fila = hoja.createRow(2 + j);

                        // Escribo el nombre del formato.
                        Cell form = fila.createCell(0);
                        form.setCellStyle(titulo);
                        form.setCellValue(formatos.get(i).getDescriptor());

                        if(ciclos != null){
                            for(int o=0; o<ciclos.size() && o<disponible.size() && o<15; o++){
                                String campos[] = new String[2];
                                campos[0] = Util.format((Date)ciclos.get(o).get("fechaEstimadaFin"), "dd/MM/yyyy");
                                campos[1] = ciclos.get(o).get("capacidadDisponible").toString();

                                for(int k=0; k<campos.length; k++){
                                    Cell cont = fila.createCell(1 + o*campos.length + k);
                                    cont.setCellStyle(contenido);
                                    cont.setCellValue(campos[k]);
                                }
                            }
                        }
                        j++;
                    }
                }    

		// Guardo el documento.
		workbook.write(outputStream);
		}



	public void listaOrdenesTrabajo(HttpServletRequest request, OutputStream outputStream) throws Exception
		{
		// Creo el archivo Excel y defino la primer hoja.
		Workbook workbook = new HSSFWorkbook();
		Sheet hoja = workbook.createSheet("Pedidos");

		// Obtengo la lista de pedidos.
		String ids[] = (request.getParameter("ids") != null)? request.getParameter("ids").split(",") : null;
		List<ReportePlanificacionNewlongCommand> ordenes = new ArrayList<ReportePlanificacionNewlongCommand>();
                                                List<OrdenTrabajo> ots = OrdenTrabajo.listar(ids);
                                                for(OrdenTrabajo o : ots ){
                                                    ReportePlanificacionNewlongCommand r = new ReportePlanificacionNewlongCommand(
                                                            o.getCicloNewlong().getNumero(),
                                                            o.getCicloNewlongTurno(), 
                                                            o);
                                                    ordenes.add(r);
                                                }
                                                Collections.sort(ordenes);
		hojaOrdenesTrabajo(hoja, 0, ordenes);
	
		// Guardo el documento.
		workbook.write(outputStream);
		}





	public void listaOrdenesVenta(HttpServletRequest request, OutputStream outputStream) throws Exception
		{
		// Creo el archivo Excel y defino la primer hoja.
		Workbook workbook = new HSSFWorkbook();
		Sheet hoja = workbook.createSheet("Pedidos");

		// Obtengo la lista de pedidos.
		String ids[] = (request.getParameter("ids") != null)? request.getParameter("ids").split(",") : null;
		List<OrdenVenta> ordenes = OrdenVenta.listar(ids);
		hojaOrdenesVenta(hoja, 0, ordenes);
	
		// Guardo el documento.
		workbook.write(outputStream);
		}

        public void programacion(HttpServletRequest request, OutputStream outputStream)throws Exception{
            if (request.getParameter("planificados").equals("No")){
                String ids[] = (request.getParameter("idsOrdenes") != null)? request.getParameter("idsOrdenes").split(",") : null;
                String idsParientes[] = (request.getParameter("idsParientes") != null)? request.getParameter("idsParientes").split(",") : null;
                programacion(request, outputStream,ids,idsParientes);
            }else{
                String ids[] = (request.getParameter("ids_planificados") != null)? request.getParameter("ids_planificados").split(",") : null;
                String idsParientes[] = (request.getParameter("idsParientesPlanificados") != null)? request.getParameter("idsParientesPlanificados").split(",") : null;
                programacion(request, outputStream,ids,idsParientes);
            }
        }
	
	
	public void programacion(HttpServletRequest request, OutputStream outputStream,String ids[], String idsParientes[]) throws Exception
		{
		Workbook workbook = new HSSFWorkbook();
                Sheet hoja = workbook.createSheet("Ordenes");
                CellStyle titulo = titulo(hoja.getWorkbook());
		CellStyle contenido = contenido(hoja.getWorkbook());

		// Escribo los titulos.
		String titulos[] = {"Work Order",
							"Fecha alta",
							"Formato",
							"Cantidad",
							"Metros",
                                                        "Logotipo",
                                                        "Estado",
							"Fecha prometida",
							"Fecha estimada fin de confección",
							"Uteco",
							"Newlong"};
		Row fila0 = hoja.createRow(0);
		for(int i=0; i<titulos.length; i++)
			{
			Cell celda = fila0.createCell(i);
			celda.setCellStyle(titulo);
			celda.setCellValue(titulos[i]);
			}
		// Obtengo la lista de ordenes de trabajo.
	        if(ids != null && ids[0].length() > 0)
			{
			for(int i=0; i<ids.length; i++)
				{
                                   OrdenTrabajo orden = null;
                                   if (ids[i].startsWith(";")){
                                          orden = new OrdenTrabajo(Integer.parseInt(ids[i].substring(1, ids[i].length())));
                                       }else{
                                          orden = new OrdenTrabajo(Integer.parseInt(ids[i]));
                                      }
                                   exportOrdenTrabajo(hoja,contenido, i + 1, orden);
				}
			}

		Sheet hojaParientes = workbook.createSheet("Parientes");
                CellStyle titulo2 = titulo(hojaParientes.getWorkbook());
		CellStyle contenido2 = contenido(hojaParientes.getWorkbook());
                Row fila2 = hojaParientes.createRow(0);
		for(int i=0; i<titulos.length; i++)
			{
			Cell celda = fila2.createCell(i);
			celda.setCellStyle(titulo2);
			celda.setCellValue(titulos[i]);
			}

                if(idsParientes != null && idsParientes[0].length() > 0)
			{
			for(int i=0; i<idsParientes.length; i++)
				{
                                   OrdenTrabajo orden = null;
                                   if (idsParientes[i].startsWith(";")){
                                          orden = new OrdenTrabajo(Integer.parseInt(idsParientes[i].substring(1, idsParientes[i].length())));
                                       }else{
                                          orden = new OrdenTrabajo(Integer.parseInt(idsParientes[i]));
                                      }
                                   exportOrdenTrabajo(hojaParientes,contenido2, i + 1, orden);
				}
			}

		workbook.write(outputStream);
		}


        private static void exportOrdenTrabajo(Sheet hoja, CellStyle contenido,int offset, OrdenTrabajo p) throws SQLException
        {
            			String msgNewlong = "";
                        if (p.getCicloNewlong() != null){
                            msgNewlong = p.getCicloNewlong().getNewlong().getDescriptor();
                        }
                        Row fila = hoja.createRow(offset);
			String valores[] = {p.getIdentificador(),
								p.getOrdenVenta().getAltaFechaHoraToString(),
								p.getFormato().getDescriptor(),
								String.valueOf(p.getCantidad()),
								String.valueOf(p.getMetros()),
                                                                p.getOrdenVenta().getLogotipo().getDescriptor(),
                                                                p.getEstado().getDescripcion(),
								Util.format(p.getFechaPrometida(), "dd/MM/yyyy"),
								Util.format(p.getCicloNewlongFin(), "dd/MM/yyyy"),
								p.getCicloUteco().getUteco().getDescriptor(),
								msgNewlong};
			for(int j=0; j<valores.length; j++)
				{
				Cell celda = fila.createCell(j);
				celda.setCellStyle(contenido);
				celda.setCellValue(valores[j]);
				}

            


        }

        public void programacionNewlong(HttpServletRequest request, OutputStream outputStream) throws Exception
		{
		// Creo el archivo Excel y defino la primer hoja.
		Workbook workbook = new HSSFWorkbook();

		// Obtengo la lista de ordenes de trabajo.
		String prog[] = (request.getParameter("ids") != null)? request.getParameter("ids").split(";") : null;
		if(prog != null && prog.length != 0)
			{
			for(int i=0; i<prog.length; i++)
				{
				if(prog[i].length() > 0 && prog[i].indexOf(":") > 0 && prog[i].indexOf(":") < prog[i].length())
					{
					String res[] = prog[i].split(":");
					if(res != null && res.length >= 2)
						{
						String ids[] = (res[1].indexOf(",") > 0)? res[1].split(",") : null;
						if(ids == null) {ids = new String[1]; ids[0] = res[1];}

						Sheet hoja = workbook.createSheet(res[0]);
                                                List<ReportePlanificacionNewlongCommand> ordenes = new ArrayList<ReportePlanificacionNewlongCommand>();
                                                List<OrdenTrabajo> ots = OrdenTrabajo.listar(ids);
                                                for(OrdenTrabajo o : ots ){
                                                    ReportePlanificacionNewlongCommand r = new ReportePlanificacionNewlongCommand(
                                                            o.getCicloNewlong().getNumero(),
                                                            o.getCicloNewlongTurno(), 
                                                            o);
                                                    ordenes.add(r);
                                                }
                                                Collections.sort(ordenes);
						hojaOrdenesTrabajo(hoja, 0, ordenes);
						}
					}
				}
			}

		// Guardo el documento.
		workbook.write(outputStream);
		}
        
        private class ReportePlanificacionNewlongCommand implements Comparable<ReportePlanificacionNewlongCommand>{
            private Integer ciclo;
            private Integer turno;
            private OrdenTrabajo ordenTrabajo;

        
            
        public ReportePlanificacionNewlongCommand(Integer ciclo, Integer turno, OrdenTrabajo ordenTrabajo) {
            this.ciclo = ciclo;
            this.turno = turno;
            this.ordenTrabajo = ordenTrabajo;
        }

        public Integer getCiclo() {
            return ciclo;
        }

        public void setCiclo(Integer ciclo) {
            this.ciclo = ciclo;
        }

        public OrdenTrabajo getOrdenTrabajo() {
            return ordenTrabajo;
        }

        public void setOrdenTrabajo(OrdenTrabajo ordenTrabajo) {
            this.ordenTrabajo = ordenTrabajo;
        }

        public Integer getTurno() {
            return turno;
        }

        public void setTurno(Integer turno) {
            this.turno = turno;
        }

        public int compareTo(ReportePlanificacionNewlongCommand o) {
            int comp = ciclo.compareTo(o.getCiclo());
            if(comp == 0){
                comp = turno.compareTo(o.getTurno());
            }
            return comp;
        }
            
            
        }




	private static void hojaOrdenesTrabajo(Sheet hoja, int offset, List<ReportePlanificacionNewlongCommand> ordenes) throws SQLException
		{
		// Defino las fuentes.
		CellStyle titulo = titulo(hoja.getWorkbook());
		CellStyle contenido = contenido(hoja.getWorkbook());

		// Escribo los titulos.
		String titulos[] = {                    "Ciclo",
                                                        "Turno",
                                                        "Work Order",
							"Fecha alta",
							"Formato",
							"Cantidad",
							"Metros",
                                                        "Logotipo",
                                                        "Estado",
							"Fecha prometida",
							"Fecha estimada fin de confección",
							"Uteco",
							"Newlong",
                                                        "Papel",
                                                        "Manija"};
		Row fila0 = hoja.createRow(offset++);
		for(int i=0; i<titulos.length; i++)
			{
			Cell celda = fila0.createCell(i);
			celda.setCellStyle(titulo);
			celda.setCellValue(titulos[i]);
			}
//                double t =0;
//try{
		for(int i=0; i<ordenes.size(); i++)
			{
                        ReportePlanificacionNewlongCommand r = ordenes.get(i);
                        OrdenTrabajo p = ordenes.get(i).getOrdenTrabajo();
			String msgNewlong = "";
                        if (p.getCicloNewlong() != null){
                            msgNewlong = p.getCicloNewlong().getNewlong().getDescriptor();
                        }
                        Row fila = hoja.createRow(i + offset);
                       
                              String estado = (p.getEstado() == null)? "": p.getEstado().getDescripcion();
								Util.format(p.getFechaPrometida(), "dd/MM/yyyy");
			String cicloNewlongFin = (p.getCicloNewlongFin() == null)?"" :Util.format(p.getCicloNewlongFin(), "dd/MM/yyyy");
			String descriptorUteco = (p.getCicloUteco()==null)?"":p.getCicloUteco().getUteco().getDescriptor();
                       
                        String ciclo = (new Integer(p.getCicloNewlong().getNumero())).toString();
                        String turno = (new Integer(p.getCicloNewlongTurno())).toString();
			String valores[] = {
                                                                r.getCiclo().toString(),
                                                                r.getTurno().toString(),
                                                                p.getIdentificador(),
								p.getOrdenVenta().getAltaFechaHoraToString(),
								p.getFormato().getDescriptor(),
								String.valueOf(p.getCantidad()),
								String.valueOf(p.getMetros()),
                                                                p.getOrdenVenta().getLogotipo().getDescriptor(),
                                                                estado,
								Util.format(p.getFechaPrometida(), "dd/MM/yyyy"),
								cicloNewlongFin,
								descriptorUteco,
								msgNewlong,
                                                                p.getOrdenVenta().getTipoPapel().getDescripcion(),
                                                                p.getOrdenVenta().getManija().getDescripcion()};
                        for(int j=0; j<valores.length; j++)
				{
				Cell celda = fila.createCell(j);
				celda.setCellStyle(contenido);
				celda.setCellValue(valores[j]);
				}
			}
//}catch(Exception e){
//    System.out.println(t);
//}
		}
        
	private static void hojaOrdenesVenta(Sheet hoja, int offset, List<OrdenVenta> ordenes) throws SQLException
		{
		// Defino las fuentes.
		CellStyle titulo = titulo(hoja.getWorkbook());
		CellStyle contenido = contenido(hoja.getWorkbook());

		// Escribo los titulos.
		String titulos[] = {"Sales order",
							"Estado",
							"Laca UV",
							"Linea",
							"Logotipo",
							"Manija",
							"Usuario",
							"Fecha alta"};
		
		Row fila0 = hoja.createRow(offset++);
		for(int i=0; i<titulos.length; i++)
			{
			Cell celda = fila0.createCell(i);
			celda.setCellStyle(titulo);
			celda.setCellValue(titulos[i]);
			}

		for(int i=0; i<ordenes.size(); i++)
			{
			OrdenVenta o = ordenes.get(i);
			Row fila = hoja.createRow(i + offset);
			String valores[] = {o.getIdentificador(),
								o.getEstado().getDescripcion(),
								o.getLacaUv().getDescripcion(),
								o.getLinea().getDescripcion(),
								o.getLogotipo().getDescripcion(),
								o.getManija().getDescripcion(),
								o.getAltaUsuario().getNombre() + " " + o.getAltaUsuario().getApellido() + " (" + o.getAltaUsuario().getUsername() + ")",
								Util.format(o.getAltaFechaHora(), "dd/MM/yyyy HH:mm:ss")};
			
			for(int j=0; j<valores.length; j++)
				{
				Cell celda = fila.createCell(j);
				celda.setCellStyle(contenido);
				celda.setCellValue(valores[j]);
				}
			}
		}
	
	
	public void listaScada(HttpServletRequest request, OutputStream outputStream) throws Exception
		{
		// Creo el archivo Excel y defino la primer hoja.
		Workbook workbook = new HSSFWorkbook();

		// Obtengo la lista de ordenes de trabajo.
		String idsXmaquinas[] = (request.getParameter("ids") != null)? request.getParameter("ids").split(";") : null;
		if(idsXmaquinas != null && idsXmaquinas.length != 0)
			{
			for(int i=0; i<idsXmaquinas.length; i++)
				{
				if(idsXmaquinas[i].length() > 0 && idsXmaquinas[i].indexOf(":") > 0 && idsXmaquinas[i].indexOf(":") < idsXmaquinas[i].length())
					{
					String idsXmaquina[] = idsXmaquinas[i].split(":");
					if(idsXmaquina != null && idsXmaquina.length >= 2)
						{
						String ids[] = (idsXmaquina[1].indexOf(",") > 0)? idsXmaquina[1].split(",") : null;
						if(ids == null) {ids = new String[1]; ids[0] = idsXmaquina[1];}

						Sheet hoja = workbook.createSheet(idsXmaquina[0]);
						hojaScada(hoja, 0, OrdenTrabajo.listar(ids));
						}
					}
				}
			}

		// Guardo el documento.
		workbook.write(outputStream);
		}

	

	private static void hojaScada(Sheet hoja, int offset, List<OrdenTrabajo> ordenes) throws SQLException
		{
		// Defino las fuentes.
		CellStyle titulo = titulo(hoja.getWorkbook());
		CellStyle contenido = contenido(hoja.getWorkbook());

		// Escribo los titulos.
		String titulos[] = {"Codigo del articulo JDE",
							"Logotipo",
							"WO-SO",
							"Formato",
							"Cantidad de bolsas",
							"Papel",
							"Manija",
							"Fecha de entrega",
							"Clasificacion",
							"Color de tarjeta de empaque",
							"Orden",
							"SQ_Formato / WO_Formato"};
		Row fila0 = hoja.createRow(offset++);
		for(int i=0; i<titulos.length; i++)
			{
			Cell celda = fila0.createCell(i);
			celda.setCellStyle(titulo);
			celda.setCellValue(titulos[i]);
			}

		for(int i=0; i<ordenes.size(); i++)
			{
			OrdenTrabajo p = ordenes.get(i);
			
			// Determino el tipo de la orden.
			String clasificacion, colorTarjeta;
			
			if(p.getFormato().getLineaId() == Linea.JUPITER || p.getFormato().getLineaId() == Linea.TIERRA_ARTESANAL)
				{
				clasificacion = "Jupiter";
				colorTarjeta = "Violeta";
				}
			else if(p.getOrdenVenta().getLogotipo().getDescripcion().toLowerCase().contains("exporta"))
				{
				clasificacion = "Exportacion";
				colorTarjeta = "Amarilla";
				}			
			else
				{
				clasificacion = "Personalizada";
				colorTarjeta = "Celeste";
				}
			
			// Obtengo el codigo y el SQ (si corresponde) de la orden
			// ESTO LO TENGO QUE HACER LEYENDO LOS VALORES DEL JDEDWARDS
			String codigo = "Desconocido";
			String SqWoFormato = "_" + p.getFormato().getDimensiones().getDescriptor();
			if(!p.getOrdenVenta().getLogotipo().isFantasia())
				{ SqWoFormato = "SQxxxxx_" + SqWoFormato; }
			else 
				{ SqWoFormato = "WO" + p.getIdentificador() + SqWoFormato; }
			
			// Escribo los valores.
			Row fila = hoja.createRow(i + offset);
			Object valores[] = {codigo,
								p.getOrdenVenta().getLogotipo().toString(),
								p.getOrdenVenta().getIdentificador() + "-" + p.getIdentificador(),
								p.getFormato().getDimensiones().getDescriptor(),
								new Double(p.getCantidad()),
								p.getOrdenVenta().getTipoPapel().getDescripcion(),
								p.getOrdenVenta().getManija().getDescripcion(),
								Util.format(p.getFechaPrometida(), "dd/MM/yyyy"),
								clasificacion,
								colorTarjeta,
								(i+1) + "",
								SqWoFormato};
			
			for(int j=0; j<valores.length; j++)
				{
				Cell celda = fila.createCell(j);
				celda.setCellStyle(contenido);
				if(valores[j] instanceof Long)
					{
					celda.setCellType(Cell.CELL_TYPE_NUMERIC);
					celda.setCellValue((Double)valores[j]);
					}
				else
					{ celda.setCellValue(valores[j].toString()); }
				}
			}
		}
	
	
	
	// ----- Metodos para inicializar fuentes ----- //

	private static CellStyle titulo(Workbook workbook)
		{
		if(workbook != null)
			{
			Font fuente = workbook.createFont();
			fuente.setBoldweight(Font.BOLDWEIGHT_BOLD);
			fuente.setColor( new HSSFColor.DARK_BLUE().getIndex() );
			fuente.setFontName("Arial");

			CellStyle celda = workbook.createCellStyle();
			celda.setAlignment(CellStyle.ALIGN_CENTER);
			celda.setDataFormat( workbook.createDataFormat().getFormat("text") );
			celda.setFont(fuente);

			return celda;
			}

		return null;
		}

	private static CellStyle contenido(Workbook workbook)
		{
		if(workbook != null)
			{
			Font fuente = workbook.createFont();
			fuente.setFontName("Arial");

			CellStyle celda = workbook.createCellStyle();
			celda.setFont(fuente);
			celda.setDataFormat( workbook.createDataFormat().getFormat("text") );

			return celda;
			}

		return null;
		}
	}

